package la.iok.hzsvn.lewin.movie.cloud.controller;

import la.iok.hzsvn.lewin.movie.cloud.entity.OrgUnit;
import la.iok.hzsvn.lewin.movie.cloud.entity.UserRole;
import la.iok.hzsvn.lewin.movie.cloud.model.OrgUnitGeo;
import la.iok.hzsvn.lewin.movie.cloud.model.OrgUnitParam;
import la.iok.hzsvn.lewin.movie.cloud.model.OrgUnitVo;
import la.iok.hzsvn.lewin.movie.cloud.service.DashBoardService;
import la.iok.hzsvn.lewin.movie.cloud.service.OrgUnitService;
import la.iok.hzsvn.lewin.movie.cloud.service.UserRoleService;
import la.iok.hzsvn.lewin.movie.cloud.service.UserService;
import la.iok.hzsvn.lewin.movie.core.RoleEnum;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.model.SimpleOrgUnitVo;
import la.iok.hzsvn.lewin.mybatis.model.PageVo;
import la.iok.hzsvn.share.collection.IdOperators;
import la.iok.hzsvn.share.response.ListDataResponse;
import la.iok.hzsvn.share.response.OperatorResponse;
import la.iok.hzsvn.share.response.OperatorResponses;
import la.iok.hzsvn.share.response.SingleDataResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("orgUnits")
public class OrgUnitController {
    private final OrgUnitService orgUnitService;
    private final UserRoleService userRoleService;
    private final UserService userService;
    private final DashBoardService dashBoardService;

    public OrgUnitController(OrgUnitService orgUnitService,
                             UserRoleService userRoleService,
                             UserService userService,
                             DashBoardService dashBoardService) {
        this.orgUnitService = orgUnitService;
        this.userRoleService = userRoleService;
        this.userService = userService;
        this.dashBoardService = dashBoardService;
    }

    @PostMapping
    public OperatorResponse add(@RequestHeader Token token, @RequestBody OrgUnitParam orgUnit){
        ErrorCode.ADMIN_DENIED.assertTrue(token.hasAnyAuthority(RoleEnum.Admin,RoleEnum.Manager));
        ErrorCode.INVALID_USER.assertNotNull(token.getUserId());
        orgUnitService.save(orgUnit,token);
        return OperatorResponses.success();
    }

    @DeleteMapping("{id}")
    public OperatorResponse delete(@RequestHeader Token token, @PathVariable Long id){
        orgUnitService.delete(id,token);
        return OperatorResponses.success();
    }

    @PutMapping("{id}")
    public OperatorResponse modify(@RequestHeader Token token, @PathVariable Long id, @RequestBody OrgUnitParam orgUnit){
        orgUnitService.update(token,id,orgUnit);
        return OperatorResponses.success();
    }
    @GetMapping
    public SingleDataResponse<PageVo<OrgUnitVo>> list(@RequestHeader Token token, int page, int limit, Integer type, String name,Long parentId){
        page = Math.max(1,page);
        limit = Math.min(Math.max(1,limit),50);
        PageVo<OrgUnitVo> pageRecords;
        if(token.hasAuthority(RoleEnum.Admin)){
            pageRecords = orgUnitService.page(page,limit,type,name,parentId);
        }else{
            pageRecords = orgUnitService.page(page,limit,type,name,token.getOrgUnitId());
        }
        return new SingleDataResponse<>(pageRecords);
    }

    /**
     * 用户所有的组织.组织切换的时候调用
     * @return 用户组织列表
     */
    @GetMapping("mine")
    public ListDataResponse<SimpleOrgUnitVo> userOrgUnits(@RequestHeader Token token){
        List<UserRole> userRoles = userRoleService.userRoles(token.getUserId());
        Set<Long> orgUnitIds = userRoles.stream().map(UserRole::getOrgUnitId).collect(Collectors.toSet());
        List<OrgUnit> orgUnits = orgUnitService.list(orgUnitIds);
        return new ListDataResponse<>(orgUnitIds.stream().map(id->{
            OrgUnit o = IdOperators.find(orgUnits,id);
            SimpleOrgUnitVo vo = new SimpleOrgUnitVo();
            if(o != null){
                BeanUtils.copyProperties(o,vo);
            } else {
                vo.setId(id);
                vo.setName("无");
            }
            return vo;
        }).collect(Collectors.toList()));
    }

    /**
     * 用户修改自己的当前组织
     * @param token 操作用户
     * @return 操作结果
     */
    @PutMapping("current/{orgUnitId}")
    public OperatorResponse current(@RequestHeader Token token,@PathVariable Long orgUnitId){
        userService.current(token,orgUnitId);
        return OperatorResponses.success();
    }

    /**
     * 邀请指定用户加入当前操作用户所在组织
     * @param token 操作用户
     * @param phoneNumber 邀请的用户手机号
     * @return 操作结果
     */
    @PostMapping("user/{phoneNumber}/{role}")
    public OperatorResponse invite(@RequestHeader Token token,@PathVariable String phoneNumber,@PathVariable String role){
        userService.invite(token,phoneNumber,role);
        return OperatorResponses.success();
    }

    @GetMapping("total")
    public SingleDataResponse<Integer> total(@RequestHeader Token token, Long orgUnitId, Integer type){
        return new SingleDataResponse<>(dashBoardService.orgUnitTotalCount(token,orgUnitId,type));
    }

    @PutMapping("{id}/online")
    public OperatorResponse online(@RequestHeader Token token, @PathVariable Long id){
        orgUnitService.online(token,id);
        return OperatorResponses.success();
    }

    @PutMapping("{id}/offline")
    public OperatorResponse offline(@RequestHeader Token token, @PathVariable Long id){
        orgUnitService.offline(token,id);
        return OperatorResponses.success();
    }

    @PostMapping("geo")
    public OperatorResponse shopGeo(@RequestHeader Token token){
        orgUnitService.buildShopGeo(token);
        return OperatorResponses.success();
    }

    @GetMapping("nearby")
    public ListDataResponse<OrgUnitGeo> nearby(Double lng, Double lat,Double radius){
        return new ListDataResponse<>(orgUnitService.geoSearch(lng,lat,radius));
    }
}
